package com.wzl.task;

import cn.binarywang.tools.generator.ChineseAddressGenerator;
import cn.binarywang.tools.generator.ChineseIDCardNumberGenerator;
import cn.binarywang.tools.generator.ChineseMobileNumberGenerator;
import cn.binarywang.tools.generator.ChineseNameGenerator;
import cn.binarywang.tools.generator.base.GenericGenerator;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wzl.constant.CommonConstant;
import com.wzl.entity.SysDictData;
import com.wzl.entity.SysEpidemData;
import com.wzl.entity.SysHistoryTrend;
import com.wzl.entity.dto.PatientInfoDTO;
import com.wzl.service.PatientInfoService;
import com.wzl.service.SysDictDataService;
import com.wzl.service.SysEpidemDataService;
import com.wzl.service.SysHistoryTrendService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wzl
 * @Description: 获取疫情数据
 * @date 2022/5/32:13
 */
@Component
@EnableScheduling
@Slf4j
public class GetEpidemDataTask {
    public static final int COUNT = 12;
    public static final int BOUND = 101;
    @Autowired
    private SysHistoryTrendService sysHistoryTrendService;
    @Autowired
    private SysEpidemDataService sysEpidemDataService;

    @Autowired
    private PatientInfoService patientInfoService;

    @Autowired
    private SysDictDataService sysDictDataService;


    @Scheduled(cron = CommonConstant.CORN)
    //在启动时运行一次
    @PostConstruct
    public void autoGetEpidemData() throws IOException {
        getDataAndSave();
        log.info("疫情数据更新成功！");
    }

    public void getDataAndSave() throws IOException {
        //清空两张表
        sysEpidemDataService.remove(new QueryWrapper<SysEpidemData>().eq("1", "1"));
        sysHistoryTrendService.remove(new QueryWrapper<SysHistoryTrend>().eq("1", "1"));
        //爬取数据，返回结果
        Connection accept = Jsoup.connect(CommonConstant.EPIDEM_DATA_URL)
                .header("Accept", "*/*")
                .header("Accept-Encoding", "gzip, deflate,br")
                .header("Accept-Language", "zh-CN,zh;q=0.9")
                .header("Content-Type", "application/json;charset=UTF-8")
                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36")
                .timeout(10000).ignoreContentType(true);
        String body = accept.execute().body();
        //替换为json格式
        String json = body.replace("aCityFunction(", "").replace(");", "");
        JSONObject jsonObject = JSON.parseObject(json);
        //获取data
        JSONObject data = jsonObject.getJSONObject("data");
        //每日新增
        JSONObject adddaily = data.getJSONObject("adddaily");
        //历史数据
        JSONArray historylist = data.getJSONArray("historylist");
        //疫情数据
        SysEpidemData sysEpidemData = new SysEpidemData();
        //转换当天数据
        extracted(data, adddaily, sysEpidemData);
        //疫情趋势数据
        List<SysHistoryTrend> sysHistoryTrends = historylist.toJavaList(SysHistoryTrend.class);
        //插入到两张表中
        sysHistoryTrendService.saveBatch(sysHistoryTrends);
        sysEpidemDataService.save(sysEpidemData);


        //模拟数据
        //数据库总患者数
        int count = patientInfoService.count();
        //数据库死亡患者数
        int deathCount = patientInfoService.count(new QueryWrapper<PatientInfoDTO>().eq("patient_state", "060"));
        //数据库治愈患者数
        int cureCount = patientInfoService.count(new QueryWrapper<PatientInfoDTO>().eq("patient_state", "070"));
        //查找到所有countyArea的区域数据
        List<SysDictData> sysDictData = sysDictDataService.getBaseMapper().selectList(new QueryWrapper<SysDictData>().eq("type_code", "countyArea"));
        //查找到所有countyArea的区域value数据
        List<String> valueList = sysDictData.stream().map(SysDictData::getValue).collect(Collectors.toList());
        //性别
        List<String> sexList = new ArrayList<>(Arrays.asList("010", "020", "030"));
        //随机数的最大值
        int len = valueList.size();
        Random random = new Random();
        //中文姓名
        ChineseNameGenerator cng = ChineseNameGenerator.getInstance();
        //手机号
        ChineseMobileNumberGenerator cmng = ChineseMobileNumberGenerator.getInstance();
        //身份证
        GenericGenerator genericGenerator = ChineseIDCardNumberGenerator.getInstance();
        //地址
        ChineseAddressGenerator cag = (ChineseAddressGenerator) ChineseAddressGenerator.getInstance();

        List<PatientInfoDTO> deathList = new ArrayList<>();
        List<PatientInfoDTO> cureList = new ArrayList<>();
        List<PatientInfoDTO> countList = new ArrayList<>();
        //新增死亡
        deathCount = Integer.parseInt(sysEpidemData.getDeathtotal()) - deathCount;
        if (deathCount != 0) {
            getList(deathCount, valueList, sexList, len, random, cng, cmng, genericGenerator, cag, "060", deathList);
            patientInfoService.saveBatch(deathList);
        }
        //新增治愈
        cureCount = Integer.parseInt(sysEpidemData.getCuretotal()) - cureCount;
        if (cureCount != 0) {
            getList(cureCount, valueList, sexList, len, random, cng, cmng, genericGenerator, cag, "070", cureList);
            patientInfoService.saveBatch(cureList);
        }
        //新增患者
        count = Integer.parseInt(sysEpidemData.getContotal()) - cureCount - deathCount - count;
        if (count != 0) {
            getList(count, valueList, sexList, len, random, cng, cmng, genericGenerator, cag, "000", countList);
            patientInfoService.saveBatch(countList);
        }

        log.info("数据同步成功！");
    }

    private void getList(int count, List<String> valueList, List<String> sexList, int len, Random random, ChineseNameGenerator cng,
                         ChineseMobileNumberGenerator cmng, GenericGenerator genericGenerator, ChineseAddressGenerator cag, String pState, List<PatientInfoDTO> list) {
        //患者状态
        List<String> pList = new ArrayList<>(Arrays.asList("010", "020", "030", "040", "050"));
        for (int i = 0; i < count; i++) {
            String id = RandomStringUtils.randomAlphanumeric(GetEpidemDataTask.COUNT);
            String name = cng.generate();
            Integer age = random.nextInt(BOUND);
            String sex = sexList.get(random.nextInt(3));
            String idCard = genericGenerator.generate();
            BigInteger phoneNumber = new BigInteger(cmng.generate());
            String infectSource = cag.generate();
            Date startTime = new Date();
            String confirmedPlace = cag.generate();
            String treatId = RandomStringUtils.randomAlphanumeric(20);
            String belongArea = valueList.get(random.nextInt(len));
            String patientState = "";
            if (!pState.equals("060") && !pState.equals("070")) {
                patientState = pList.get(random.nextInt(5));
            } else {
                patientState = pState;
            }
            list.add(new PatientInfoDTO(id, name, age, sex, idCard, phoneNumber, infectSource, startTime,
                    confirmedPlace, treatId, belongArea, patientState, 0));
        }
    }

    private void extracted(JSONObject data, JSONObject adddaily, SysEpidemData sysEpidemData) {
        sysEpidemData.setContotal(data.getString("contotal"));
        sysEpidemData.setCuretotal(data.getString("curetotal"));
        sysEpidemData.setDeathtotal(data.getString("deathtotal"));
        sysEpidemData.setEconnum(data.getString("econNum"));
        sysEpidemData.setTime(data.getString("mtime"));
        sysEpidemData.setConadd(adddaily.getString("conadd_n"));
        sysEpidemData.setCureadd(adddaily.getString("cureadd_n"));
        sysEpidemData.setDeathadd(adddaily.getString("deathadd_n"));
        sysEpidemData.setEconadd(adddaily.getString("conadd_n"));
    }
}
